package top.v5it.logback.push;

import ch.qos.logback.core.UnsynchronizedAppenderBase;
import ch.qos.logback.core.encoder.Encoder;
import ch.qos.logback.core.spi.AppenderAttachable;
import top.v5it.logback.push.channel.ChannelPushStrategy;
import top.v5it.logback.push.channel.mail.MailChannelPushStrategy;
import top.v5it.logback.push.channel.weixin.WeiXinChannelPushStrategy;
import top.v5it.logback.push.convergence.ConvergenceStrategy;
import top.v5it.logback.push.convergence.NotConvergenceStrategy;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author zhanpu
 * @date 2022/9/2
 */
public abstract class PushAppenderConfig<E> extends UnsynchronizedAppenderBase<E> implements AppenderAttachable<E> {

    protected Encoder<E> encoder = null;
    protected Map<String, Object> pushConfig = new HashMap<>();
    protected ChannelPushStrategy channelPushStrategy;
    protected ConvergenceStrategy convergenceStrategy;

    protected boolean checkPrerequisites() {
        boolean errorFree = true;

        if (encoder == null) {
            addError("No encoder set for the appender named [\"" + name + "\"].");
            errorFree = false;
        }

        if (channelPushStrategy == null) {
            addInfo("No explicit channelPushStrategy set for the appender named [\"" + name
                    + "\"]. Using default weixin strategy.");
            channelPushStrategy = new WeiXinChannelPushStrategy();
        }

        if (convergenceStrategy == null) {
            addInfo("No explicit convergenceStrategy set for the appender named [\"" + name
                    + "\"]. Using default notConvergence strategy.");
            convergenceStrategy = new NotConvergenceStrategy();
        }

        if (!(channelPushStrategy instanceof MailChannelPushStrategy)) {
            if (pushConfig.get("server.url") == null) {
                addError("No \"server.url\" set for the appender named [\"" + name + "\"].");
                errorFree = false;
            }
        } else {
            if (pushConfig.get("contacts") == null) {
                addError("No \"contacts\" set for the appender named [\"" + name + "\"].");
                errorFree = false;
            }
        }

        return errorFree;
    }

    public void setEncoder(Encoder<E> encoder) {
        this.encoder = encoder;
    }

    public void addPushConfig(String keyValue) {
        Optional.ofNullable(keyValue)
                .map(t -> t.split("=", 2))
                .filter(t -> t.length == 2)
                .ifPresent(t -> addPushConfigValue(t[0], t[1]));
    }

    public void addPushConfigValue(String key, Object value) {
        this.pushConfig.put(key, value);
    }

    public Map<String, Object> getPushConfig() {
        return pushConfig;
    }

    public void setChannelPushStrategy(ChannelPushStrategy channelPushStrategy) {
        this.channelPushStrategy = channelPushStrategy;
    }

    public void setConvergenceStrategy(ConvergenceStrategy convergenceStrategy) {
        this.convergenceStrategy = convergenceStrategy;
    }
}
